#ifndef _N2F_DELEGATE_H_
#define _N2F_DELEGATE_H_

#include "core.h"

namespace N2F
{
	namespace Iw3D
	{
		void DefaultNotificationCallback(void *eventData, void *userData);
		bool DefaultSystemCallback(void *eventData, void *userData);

		class Delegate
		{
		public:
			typedef void (*NotificationCallback)(void *, void *);
			typedef bool (*SystemCallback)(void *, void *);

		private:
			struct NotificationCallbackInfo
			{
				NotificationCallback callback;
				void *userData;

				NotificationCallbackInfo(NotificationCallback callback, void *data);
			};

			struct SystemCallbackInfo
			{
				SystemCallback callback;
				void *userData;

				SystemCallbackInfo(SystemCallback callback, void *data);
			};

		public:
			typedef std::multimap<int, NotificationCallbackInfo> NotificationList;
			typedef std::pair<int, NotificationCallbackInfo> NotificationListItem;
			typedef std::multimap<int, NotificationCallbackInfo>::iterator NotificationListIter;

			typedef std::map<int, SystemCallbackInfo> SystemList;
			typedef std::pair<int, SystemCallbackInfo> SystemListItem;
			typedef std::map<int, SystemCallbackInfo>::iterator SystemListIter;

			Delegate();
			~Delegate();

			bool hookNotificationEvent(int key, NotificationCallback callback, void *userData);
			bool hookSystemEvent(int key, SystemCallback callback, void *userData);

		protected:
			bool registerNotificationEvent(int key);
			bool registerSystemEvent(int key);

			void touchNotificationEvent(int key, void *eventData);
			void touchSystemEvent(int key, void *eventData);

			NotificationList notificationEvents;
			SystemList systemEvents;
		};
	}
}

#endif
